package com.jh.shuibowen;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ShuiBoView extends View {

    public static final String TAG = "ShuiBoView";
    private Context mContext;
    private Paint mPaint;
    private Path mBezier;
    private int rootWidth, rootHeight;
    PorterDuffXfermode mPorterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
    private List<ShuiBoBean> mBoBeanList = new ArrayList<>();

    DecimalFormat mDecimalFormat = new DecimalFormat("00.00");

    private float proportion = 0;
    private String propStr = "00.00";

    AnimatorSet mAnimatorSet = new AnimatorSet();

    public ShuiBoView(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public ShuiBoView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }

    public ShuiBoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        init();
    }

    public ShuiBoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext = context;
        init();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        rootWidth = getWidth();
        rootHeight = getHeight();
    }

    ValueAnimator mScaleAnimator;
    float scale = 1;
    private void init(){
        mPaint = new Paint();
        mBezier = new Path();

        List<ShuiBoBean> initSuibo = new ArrayList<>();
        initSuibo.add(new ShuiBoBean(true, getResources().getColor(R.color.blue_100, null), getResources().getColor(R.color.blue_200, null), 500, 30, 2000));
        initSuibo.add(new ShuiBoBean(true, getResources().getColor(R.color.gray_100, null), getResources().getColor(R.color.gray_200, null), 500, 40, 1000));
        addShuiBo(initSuibo);

        mScaleAnimator = ValueAnimator.ofFloat(scale, 0.9f);
        mScaleAnimator.setDuration(200);
        mScaleAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mScaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                scale = (float) animation.getAnimatedValue();
                setScaleX(scale);
                setScaleY(scale);
            }
        });

        setTranslationZ(50);
        setOutlineSpotShadowColor(getResources().getColor(R.color.blue_200, null));
        setOutlineAmbientShadowColor(getResources().getColor(R.color.blue_200, null));
        setClickable(true);

        setClipToOutline(true);
        setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                Path path = new Path();
                path.addCircle(1.0f*view.getWidth()/2, 1.0f*view.getHeight()/2, 1.0f*view.getWidth()/2, Path.Direction.CCW);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    outline.setPath(path);
                }
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mScaleAnimator.start();
                break;
            case MotionEvent.ACTION_UP:
                mScaleAnimator.reverse();
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        int count = canvas.saveLayer(0, 0, rootWidth, rootHeight, mPaint);

        for (ShuiBoBean shuiBoBean : mBoBeanList) {
            mBezier.reset();
            if (shuiBoBean.isFill){
                mPaint.setStyle(Paint.Style.FILL);
            }else{
                mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setStrokeWidth(1);
            }
            LinearGradient linearGradient = new LinearGradient(rootWidth, 0, rootWidth, rootHeight, new int[]{shuiBoBean.shuiStartColor, shuiBoBean.shuiEndColor}, null, Shader.TileMode.CLAMP);
            mPaint.setShader(linearGradient);
            int halfWidth = (int) (1.0f * shuiBoBean.shuiWidth / 2);
            mBezier.moveTo(-shuiBoBean.shuiWidth + shuiBoBean.shuiOffset, rootHeight - (1.0f * this.proportion * rootHeight / 100) - 1.0f*shuiBoBean.shuiHeight/2);
            for (int i = 0; i < shuiBoBean.shuiWidth + rootWidth ; i+=shuiBoBean.shuiWidth) {
                mBezier.rQuadTo(1.0f*halfWidth/2, -shuiBoBean.shuiHeight, halfWidth, 0);
                mBezier.rQuadTo(1.0f*halfWidth/2, shuiBoBean.shuiHeight, halfWidth, 0);
            }
            mBezier.lineTo(getWidth(), getHeight());
            mBezier.lineTo(0, getHeight());
            mBezier.close();
            canvas.drawPath(mBezier, mPaint);
        }
        mPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.shuiboview_text_size));
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setTypeface(Typeface.DEFAULT_BOLD);
        LinearGradient linearGradient = new LinearGradient(rootWidth, 0, rootWidth, rootHeight, new int[]{Color.WHITE, Color.WHITE}, null, Shader.TileMode.CLAMP);
        mPaint.setShader(linearGradient);
        mPaint.setXfermode(mPorterDuffXfermode);
        Paint.FontMetricsInt fontMetricsInt1 = mPaint.getFontMetricsInt();
        float dy = (fontMetricsInt1.bottom - fontMetricsInt1.top) * 1.0f / 2 - fontMetricsInt1.bottom;
        canvas.drawText(propStr, 1.0f*rootWidth/2, 1.0f*rootHeight/2 + dy, mPaint);
        mPaint.setXfermode(null);

        /* 画中仙
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
        canvas.drawLine(1.0f*rootWidth/2, 0, 1.0f*rootWidth/2, 1024, paint);
        canvas.drawLine(0, 1.0f*rootHeight/2, 1024, 1.0f*rootHeight/2, paint);
         */
    }

    public void addShuiBo(List<ShuiBoBean> beans){
        if (beans == null) return;
        if (!mBoBeanList.isEmpty()){
            mBoBeanList.clear();
        }
        mBoBeanList.addAll(beans);
        startAnimator();
    }

    float oldProp = proportion;
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 0);
    public void setProp(float prop){
        valueAnimator.setFloatValues(oldProp, prop);
        valueAnimator.setDuration(1000);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                proportion = (float) animation.getAnimatedValue();
                propStr = mDecimalFormat.format(proportion);
                oldProp = proportion;
                invalidate();
            }
        });
        valueAnimator.start();
    }

    public void initValueAnimator(){
        List<Animator> animators = new ArrayList<>();
        for (int i = 0; i < mBoBeanList.size(); i++) {
            ShuiBoBean shuiBoBean = mBoBeanList.get(i);
            ValueAnimator v;
            v = ValueAnimator.ofFloat( 0, shuiBoBean.shuiWidth);
            /*
            if (i%2==0){
                v = ValueAnimator.ofFloat( 0, shuiBoBean.shuiWidth);
            }else{
                v = ValueAnimator.ofFloat(shuiBoBean.shuiWidth, 0);
            }
             */
            v.setDuration(shuiBoBean.shuiDuration);
            v.setInterpolator(new LinearInterpolator());
            v.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                    shuiBoBean.shuiOffset = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            v.setRepeatCount(-1);
            animators.add(v);
        }
        mAnimatorSet.playTogether(animators);
    }
    private void startAnimator(){
        initValueAnimator();
        if (mAnimatorSet.isRunning()){
            mAnimatorSet.cancel();
        }
        mAnimatorSet.start();
    }
}
